package org.boyan.modules.config.b;


import com.alibaba.druid.filter.config.ConfigTools;
import freemarker.template.TemplateException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.boyan.common.util.SpringContextUtils;
import org.boyan.common.util.oConvertUtils;
import org.boyan.modules.cgform.entity.OnlCgformField;
import org.boyan.modules.config.a.b;
import org.boyan.modules.config.exception.DBException;
import org.boyan.modules.config.service.DbTableHandleI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author: zhuxiaobao
 * @time: 2021/9/24 17:30
 */

public class c {
    private static final Logger alog = LoggerFactory.getLogger(c.class);

    private static final String b = "org/boyan/modules/config/engine/tableTemplate.ftl";

    private static DbTableHandleI c;

    public c() throws SQLException, DBException {
        c = d.getTableHandle();
    }

    public static void a(org.boyan.modules.config.a.a parama) throws IOException, TemplateException, HibernateException, SQLException, DBException {
        String str1 = d.getDatabaseType();
        if ("ORACLE".equals(str1)) {
            ArrayList<OnlCgformField> arrayList = new ArrayList<>();
            for (OnlCgformField onlCgformField : parama.getColumns()) {
                if ("int".equals(onlCgformField.getDbType())) {
                    onlCgformField.setDbType("double");
                    onlCgformField.setDbPointLength(0);
                }
                arrayList.add(onlCgformField);
            }
            parama.setColumns(arrayList);
        }
        String str2 = g.a("org/boyan/modules/config/engine/tableTemplate.ftl", a(parama, str1));
        alog.info(str2);
        HashMap<Object, Object> hashMap = new HashMap<>();
        b b = parama.getDbConfig();
        hashMap.put("hibernate.connection.driver_class", b.getDriverClassName());
        hashMap.put("hibernate.connection.url", b.getUrl());
        hashMap.put("hibernate.connection.username", b.getUsername());
        String str3 = b.getPassword();
        if (str3 != null) {
            if (b.getDruid() != null && oConvertUtils.isNotEmpty(b.getDruid().getPublicKey())) {
                alog.info(" dbconfig.getDruid().getPublicKey() = " + b.getDruid().getPublicKey());
                try {
                    String str = ConfigTools.decrypt(b.getDruid().getPublicKey(), str3);
                    alog.info(" decryptPassword = " + str);
                    hashMap.put("hibernate.connection.password", str);
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            } else {
                hashMap.put("hibernate.connection.password", str3);
            }
        }
        hashMap.put("hibernate.show_sql", Boolean.TRUE);
        hashMap.put("hibernate.format_sql", Boolean.TRUE);
        hashMap.put("hibernate.temp.use_jdbc_metadata_defaults", Boolean.FALSE);
        hashMap.put("hibernate.dialect", d.b(str1));
        hashMap.put("hibernate.hbm2ddl.auto", "create");
        hashMap.put("hibernate.connection.autocommit", Boolean.FALSE);
        hashMap.put("hibernate.current_session_context_class", "thread");
        StandardServiceRegistry standardServiceRegistry = (new StandardServiceRegistryBuilder()).applySettings(hashMap).build();
        MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(str2.getBytes(StandardCharsets.UTF_8));
        metadataSources.addInputStream(byteArrayInputStream);
        Metadata metadata = metadataSources.buildMetadata();
        SchemaExport schemaExport = new SchemaExport();
        schemaExport.create(EnumSet.of(TargetType.DATABASE), metadata);
        byteArrayInputStream.close();
        List<Exception> list = schemaExport.getExceptions();
        for (Exception exception : list) {
            if ("java.sql.SQLSyntaxErrorException".equals(exception.getCause().getClass().getName())) {
                SQLSyntaxErrorException sQLSyntaxErrorException = (SQLSyntaxErrorException)exception.getCause();
                if ("42000".equals(sQLSyntaxErrorException.getSQLState())) {
                    if (1064 == sQLSyntaxErrorException.getErrorCode() || 903 == sQLSyntaxErrorException.getErrorCode()) {
                        throw new DBException("");
                    }
                    continue;
                }
            } else {
                if ("com.microsoft.sqlserver.jdbc.SQLServerException".equals(exception.getCause().getClass().getName())) {
                    if (exception.getCause().toString().contains("Incorrect syntax near the keyword")) {
                        exception.printStackTrace();
                        throw new DBException(exception.getCause().getMessage());
                    }
                    alog.info(exception.getMessage());
                    continue;
                }
                if ("DM".equals(str1)) {
                    String str = exception.getMessage();
                    if (str != null && str.contains("Error executing DDL \"drop table")) {
                        alog.info(str);
                        continue;
                    }
                }
            }
            throw new DBException(exception.getMessage());
        }
    }

    public List<String> b(org.boyan.modules.config.a.a parama) throws DBException, SQLException {
        String str1 = d.getDatabaseType();
        String str2 = d.a(parama.getTableName(), str1);
        String str3 = "alter table  " + str2 + " ";
        ArrayList<String> arrayList = new ArrayList();
        try {
            Map<String, a> map1 = c(null, str2);
            Map<String, a> map2 = c(parama);
            Map<String, String> map = a(parama.getColumns());
            for (String str : map2.keySet()) {
                if (!map1.containsKey(str)) {
                    a a3 = map2.get(str);
                    String str4 = map.get(str);
                    if (map.containsKey(str) && map1.containsKey(str4)) {
                        a a4 = map1.get(str4);
                        String str5 = c.getReNameFieldName(a3);
                        if ("SQLSERVER".equals(str1)) {
                            arrayList.add(str5);
                        } else {
                            arrayList.add(str3 + str5);
                        }
                        String str6 = d(str, a3.getColumnId());
                        arrayList.add(str6);
                        if (!a4.equals(a3)) {
                            arrayList.add(str3 + a(a3, a4));
                            if ("POSTGRESQL".equals(str1)) {
                                arrayList.add(str3 + b(a3, a4));
                            }
                        }
                        if (!"SQLSERVER".equals(str1) && !a4.b(a3)) {
                            arrayList.add(c(a3));
                        }
                        continue;
                    }
                    arrayList.add(str3 + b(a3));
                    if (!"SQLSERVER".equals(str1) && StringUtils.isNotEmpty(a3.getComment())) {
                        arrayList.add(c(a3));
                    }
                    continue;
                }
                a a1 = map1.get(str);
                a a2 = map2.get(str);
                if (!a1.a(a2, str1)) {
                    arrayList.add(str3 + a(a2, a1));
                }
                if (!"SQLSERVER".equals(str1) && !"ORACLE".equals(str1) && !a1.b(a2)) {
                    arrayList.add(c(a2));
                }
            }
            for (String str : map1.keySet()) {
                if (!map2.containsKey(str.toLowerCase()) && !map.containsValue(str.toLowerCase())) {
                    arrayList.add(str3 + b(str));
                }
            }
        } catch (SQLException sQLException) {
            throw new RuntimeException();
        }
        alog.info(" db update sql : " + arrayList.toString());
        return arrayList;
    }

    private static Map<String, Object> a(org.boyan.modules.config.a.a parama, String paramString) {
        HashMap<Object, Object> hashMap = new HashMap<>();
        for (OnlCgformField onlCgformField : parama.getColumns()) {
            onlCgformField.setDbDefaultVal(c(onlCgformField.getDbDefaultVal()));
        }
        hashMap.put("entity", parama);
        hashMap.put("dataType", paramString);
        return (Map)hashMap;
    }

    private Map<String, a> c(String paramString1, String paramString2) throws SQLException {
        HashMap<Object, Object> hashMap = new HashMap<>();
        Connection connection = null;
        try {
            connection = d.getConnection();
        } catch (Exception exception) {
            alog.info(exception.getMessage(), exception);
        }
        DatabaseMetaData databaseMetaData = connection.getMetaData();
        b b = (b)SpringContextUtils.getBean(b.class);
        String str1 = null;
        try {
            str1 = d.getDatabaseType();
        } catch (DBException dBException) {
            dBException.printStackTrace();
        }
        String str2 = b.getUsername();
        if ("ORACLE".equals(str1)) {
            str2 = str2.toUpperCase();
        }
        ResultSet resultSet = null;
        if ("SQLSERVER".equals(str1)) {
            resultSet = databaseMetaData.getColumns(connection.getCatalog(), null, paramString2, "%");
        } else {
            resultSet = databaseMetaData.getColumns(connection.getCatalog(), str2, paramString2, "%");
        }
        while (resultSet.next()) {
            a a = new a();
            a.setTableName(paramString2);
            String str3 = resultSet.getString("COLUMN_NAME").toLowerCase();
            a.setColumnName(str3);
            String str4 = resultSet.getString("TYPE_NAME");
            int i = resultSet.getInt("DECIMAL_DIGITS");
            String str5 = c.getMatchClassTypeByDataType(str4, i);
            a.setColunmType(str5);
            a.setRealDbType(str4);
            int j = resultSet.getInt("COLUMN_SIZE");
            a.setColumnSize(j);
            a.setDecimalDigits(i);
            String str6 = (resultSet.getInt("NULLABLE") == 1) ? "Y" : "N";
            a.setIsNullable(str6);
            String str7 = resultSet.getString("REMARKS");
            a.setComment(str7);
            String str8 = resultSet.getString("COLUMN_DEF");
            String str9 = (c(str8) == null) ? "" : c(str8);
            a.setFieldDefault(str9);
            alog.info("getColumnMetadataFormDataBase --->COLUMN_NAME:" + str3.toUpperCase() + " TYPE_NAME :" + str4 + " DECIMAL_DIGITS:" + i + " COLUMN_SIZE:" + j);
            hashMap.put(str3, a);
        }
        return (Map)hashMap;
    }

    private Map<String, a> c(org.boyan.modules.config.a.a parama) {
        HashMap<Object, Object> hashMap = new HashMap<>();
        List<OnlCgformField> list = parama.getColumns();
        for (OnlCgformField onlCgformField : list) {
            a a1 = new a();
            a1.setTableName(parama.getTableName().toLowerCase());
            a1.setColumnId(onlCgformField.getId());
            a1.setColumnName(onlCgformField.getDbFieldName().toLowerCase());
            a1.setColumnSize(onlCgformField.getDbLength().intValue());
            a1.setColunmType(onlCgformField.getDbType().toLowerCase());
            a1.setIsNullable((onlCgformField.getDbIsNull().intValue() == 1) ? "Y" : "N");
            a1.setComment(onlCgformField.getDbFieldTxt());
            a1.setDecimalDigits(onlCgformField.getDbPointLength().intValue());
            a1.setFieldDefault(c(onlCgformField.getDbDefaultVal()));
            a1.setPkType((parama.getJformPkType() == null) ? "UUID" : parama.getJformPkType());
            a1.setOldColumnName((onlCgformField.getDbFieldNameOld() != null) ? onlCgformField.getDbFieldNameOld().toLowerCase() : null);
            alog.info("getColumnMetadataFormCgForm ----> DbFieldName: " + onlCgformField.getDbFieldName().toLowerCase() + " | DbType: " + onlCgformField.getDbType().toLowerCase() + " | DbPointLength:" + onlCgformField
                    .getDbPointLength() + " | DbLength:" + onlCgformField.getDbLength());
            hashMap.put(onlCgformField.getDbFieldName().toLowerCase(), a1);
        }
        return (Map)hashMap;
    }

    private Map<String, String> a(List<OnlCgformField> paramList) {
        HashMap<Object, Object> hashMap = new HashMap<>();
        for (OnlCgformField onlCgformField : paramList) {
            hashMap.put(onlCgformField.getDbFieldName(), onlCgformField.getDbFieldNameOld());
        }
        return (Map)hashMap;
    }

    private String b(String paramString) {
        return c.getDropColumnSql(paramString);
    }

    private String a(a parama1, a parama2) throws DBException {
        return c.getUpdateColumnSql(parama1, parama2);
    }

    private String b(a parama1, a parama2) {
        return c.getSpecialHandle(parama1, parama2);
    }

    private String a(a parama) {
        return c.getReNameFieldName(parama);
    }

    private String b(a parama) {
        return c.getAddColumnSql(parama);
    }

    private String c(a parama) {
        return c.getCommentSql(parama);
    }

    private String d(String paramString1, String paramString2) {
        return "update onl_cgform_field set DB_FIELD_NAME_OLD = '" + paramString1 + "' where ID ='" + paramString2 + "'";
    }

    private int a(String paramString1, String paramString2, Session paramSession) {
        return paramSession.createSQLQuery("update onl_cgform_field set DB_FIELD_NAME_OLD= '" + paramString1 + "' where ID ='" + paramString2 + "'").executeUpdate();
    }

    private static String c(String paramString) {
        if (StringUtils.isNotEmpty(paramString)) {
            try {
                Double.valueOf(paramString);
            } catch (Exception exception) {
                if (!paramString.startsWith("'") || !paramString.endsWith("'")) {
                    paramString = "'" + paramString + "'";
                }
            }
        }
        return paramString;
    }

    public String a(String paramString1, String paramString2) {
        return c.dropIndexs(paramString1, paramString2);
    }

    public String b(String paramString1, String paramString2) {
        return c.countIndex(paramString1, paramString2);
    }

    public static List<String> a(String paramString) throws SQLException {
        Connection connection = null;
        ResultSet resultSet = null;
        ArrayList<String> arrayList = new ArrayList();
        try {
            connection = d.getConnection();
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            resultSet = databaseMetaData.getIndexInfo(null, null, paramString, false, false);
            ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
            while (resultSet.next()) {
                String str = resultSet.getString("INDEX_NAME");
                if (oConvertUtils.isEmpty(str)) {
                    str = resultSet.getString("index_name");
                }
                if (oConvertUtils.isNotEmpty(str)) {
                    arrayList.add(str);
                }
            }
        } catch (SQLException sQLException) {
            alog.info(sQLException.getMessage(), sQLException);
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return arrayList;
    }
}

